//
//  APIService.swift
//  Progress
//
//  Created by bin hu on 2025/6/30.
//

import Alamofire

// MARK: - 数据模型
struct ServerConfig: Codable {
    let apiEndpoints: [String]
    let socketEndpoints: [String]
    let ttl: TimeInterval
}

struct APIResponse<T: Codable>: Codable {
    let code: Int
    let message: String
    let data: T
}

// MARK: - 错误处理
enum APIError: Error {
    case allDomainsFailed
    case invalidResponse
    case networkError(Error)
    case configError
}

// MARK: - 辅助扩展
extension Error {
    var isExplicitlyCancelledError: Bool {
        let nsError = self as NSError
        return nsError.domain == NSURLErrorDomain && nsError.code == NSURLErrorCancelled
    }
}

// MARK: - API 服务
class APIService {
    static let shared = APIService()
    
    private var currentRequests: [String: DataRequest] = [:]
    private let queue = DispatchQueue(label: "com.domain.api.queue", attributes: .concurrent)
    
    func request<T: Codable>(
        _ endpoint: String,
        method: HTTPMethod = .get,
        parameters: Parameters? = nil,
        headers: HTTPHeaders? = nil,
        completion: @escaping (Result<T, APIError>) -> Void
    ) {
        // 递归请求方法
        func attemptRequest(attempt: Int = 0, lastError: APIError? = nil) {
            guard let domain = DynamicDomainManager.shared.getOptimalAPIDomain() else {
                completion(.failure(.configError))
                return
            }
            
            let fullURL = "\(domain)\(endpoint)"
            let requestKey = "\(method.rawValue)|\(fullURL)"
            
            // 取消之前的相同请求
            queue.async(flags: .barrier) { [weak self] in
                self?.currentRequests[requestKey]?.cancel()
            }
            
            let request = AF.request(
                fullURL,
                method: method,
                parameters: parameters,
                headers: headers
            )
            
            queue.async(flags: .barrier) { [weak self] in
                self?.currentRequests[requestKey] = request
            }
            
            request.validate().responseDecodable(of: APIResponse<T>.self) { [weak self] response in
                self?.queue.async(flags: .barrier) {
                    self?.currentRequests.removeValue(forKey: requestKey)
                }
                
                switch response.result {
                case .success(let responseData):
                    if responseData.code == 200 {
                        DynamicDomainManager.shared.markDomainHealthy(domain)
                        completion(.success(responseData.data))
                    } else {
                        // 业务错误不重试
                        completion(.failure(.invalidResponse))
                    }
                    
                case .failure(let error):
                    if error.isExplicitlyCancelledError {
                        return // 忽略取消错误
                    }
                    
                    // 标记域名不健康
                    DynamicDomainManager.shared.markDomainUnhealthy(domain)
                    
                    // 特殊错误不重试
                    if let afError = error.asAFError,
                       afError.isResponseValidationError,
                       let statusCode = afError.responseCode,
                       (400..<500).contains(statusCode) {
                        completion(.failure(.invalidResponse))
                        return
                    }
                    
                    // 指数退避重试
                    let delay = min(pow(2.0, Double(attempt)), 5.0)
                    
                    DispatchQueue.global().asyncAfter(deadline: .now() + delay) {
                        attemptRequest(attempt: attempt + 1, lastError: .networkError(error))
                    }
                }
            }
        }
        
        attemptRequest()
    }
}


